﻿/*
Typps HTML Editor for ASP.NET
FULL EDITION

Copyright (c) 2009 Alessandro Zifiglio, http://www.Typps.com
EMail: alessandro@Typps.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
Typps.ColorPicker=function (element) {
    Typps.ColorPicker.initializeBase(this,[element]);
    this._className=null;
    this._commandName=null;
    this._commandArgument=null;
    this._colorMouseOutDelegate=null;
    this._colorSelectDelegate=null;
    this._colorMouseOverDelegate=null;

    this._callbacks=null;
    this._display=null;
    this._shaderColor='#000';
    this._shaderOpacity=20;
    this._className=null;
    this._timeout=0;
    this._cancelButtonDelegate=null;
    this._okButtonDelegate=null;
    this._targetControlId=null;
    this._targetControlDelegate=null;
    this._mouseDownDelegate=null;
    this._popperId=null;
    this._targetControlActivationOn=null;
    this._formElementId=null;
    this._postbackAllFormData=null;
    this._title=null;
    this._uniqueId=null;
    this._updatePanelProgressId=null;

    this._beginRequestHandlerDelegate=null;
    this._endRequestHandlerDelegate=null;
    this._abortRequestHandlerDelegate=null;
}
Typps.ColorPicker.prototype={
    get_uniqueId: function () {
        return this._uniqueId;
    },
    set_uniqueId: function (value) {
        this._uniqueId=value;
    },
    get_updatePanelProgressId: function () {
        return this._updatePanelProgressId;
    },
    set_updatePanelProgressId: function (value) {
        this._updatePanelProgressId=value;
    },
    get_element: function () {
        return this._element;
    },
    get_commandName: function () {
        return (this._commandName==null)?'':this._commandName;
    },
    set_commandName: function (value) {
        this._commandName=value;
    },
    get_commandArgument: function () {
        return this._commandArgument;
    },
    set_commandArgument: function (value) {
        this._commandArgument=value;
    },
    get_updatePanelProgressId: function () {
        return this._updatePanelProgressId;
    },
    set_updatePanelProgressId: function (value) {
        this._updatePanelProgressId=value;
    },
    get_timeout: function () {
        return this._timeout;
    },
    set_timeout: function (value) {
        this._timeout=value;
    },
    get_targetControlActivationOn: function () {
        return (this._targetControlActivationOn==null)?'click':this._targetControlActivationOn;
    },
    set_targetControlActivationOn: function (value) {
        this._targetControlActivationOn=value;
    },
    get_title: function () {
        return this._title;
    },
    set_title: function (value) {
        this._title=value;
    },
    get_callbacks: function () {
        return this._callbacks;
    },
    set_callbacks: function (value) {
        this._callbacks=value;
    },
    get_targetControlId: function () {
        return this._targetControlId;
    },
    set_targetControlId: function (value) {
        this._targetControlId=value;
    },
    get_display: function () {
        return (this._display==null)?false:this._display;
    },
    set_display: function (value) {
        this._display=value;
    },
    /// <param name="method" type="Property">
    /// The className, so you can style the popup.
    ///</param>
    get_className: function () {
        return this._className;
    },
    set_className: function (value) {
        this._className=value;
    },
    /// <param name="method" type="Property">
    /// The color of the shader in the background when isModal is true.
    ///</param>
    get_shaderColor: function () {
        return this._shaderColor;
    },
    set_shaderColor: function (value) {
        this._shaderColor=value;
    },
    get_shaderOpacity: function () {
        return this._shaderOpacity;
    },
    set_shaderOpacity: function (value) {
        this._shaderOpacity=value;
    },
    get_formElementId: function () {
        return this._formElementId;
    },
    set_formElementId: function (value) {
        this._formElementId=value;
    },
    get_postbackAllFormData: function () {
        return this._postbackAllFormData;
    },
    set_postbackAllFormData: function (value) {
        this._postbackAllFormData=value;
    },
    add_targetControl: function (handler) {
        this.get_events().addHandler('target',handler);
    },
    remove_targetControl: function (handler) {
        this.get_events().removeHandler('target',handler);
    },
    add_cancelButton: function (handler) {
        this.get_events().addHandler('cancel',handler);
    },
    remove_cancelButton: function (handler) {
        this.get_events().removeHandler('cancel',handler);
    },
    add_okButton: function (handler) {
        this.get_events().addHandler('ok',handler);
    },
    remove_okButton: function (handler) {
        this.get_events().removeHandler('ok',handler);
    },
    add_beginWebRequest: function (handler) {
        this.get_events().addHandler('beginWebRequest',handler);
    },
    remove_beginWebRequest: function (handler) {
        this.get_events().removeHandler('beginWebRequest',handler);
    },
    add_endWebRequest: function (handler) {
        this.get_events().addHandler('endWebRequest',handler);
    },
    remove_endWebRequest: function (handler) {
        this.get_events().removeHandler('endWebRequest',handler);
    },
    add_colorMouseOut: function (handler) {
        this.get_events().addHandler('colorMouseOut',handler);
    },
    remove_colorMouseOut: function (handler) {
        this.get_events().removeHandler('colorMouseOut',handler);
    },
    add_colorSelect: function (handler) {
        this.get_events().addHandler('colorSelect',handler);
    },
    remove_colorSelect: function (handler) {
        this.get_events().removeHandler('colorSelect',handler);
    },
    add_colorMouseOver: function (handler) {
        this.get_events().addHandler('colorMouseOver',handler);
    },
    remove_colorMouseOver: function (handler) {
        this.get_events().removeHandler('colorMouseOver',handler);
    },
    add_colorPickerInitialize: function (handler) {
        this.get_events().addHandler('colorPickerInitialize',handler);
    },
    remove_colorPickerInitialize: function (handler) {
        this.get_events().removeHandler('colorPickerInitialize',handler);
    },
    dispose: function () {
        var colorPicker=$get(this.get_id()+'_colorPicker');
        if(this._colorSelectDelegate) {
            if(colorPicker!=null) {
                var tdCol=colorPicker.getElementsByTagName('a');
                for(var num2=0;num2<tdCol.length;num2++) {
                    var a=tdCol[num2];
                    Sys.UI.DomEvent.removeHandler(a,'click',this._colorSelectDelegate);
                    Sys.UI.DomEvent.removeHandler(a,'mousedown',this._mouseDownDelegate);
                    Sys.UI.DomEvent.removeHandler(a,'mouseover',this._colorMouseOverDelegate);
                    Sys.UI.DomEvent.removeHandler(a,'mouseout',this._colorMouseOutDelegate);
                }
            }
            delete this._colorSelectDelegate;
            delete this._colorMouseOverDelegate;
            delete this._colorMouseOutDelegate;
        }
        if(this._radioR!=null) {
            Sys.UI.DomEvent.removeHandler(this._radioR,'click',this._radioClickedDelegate);
            Sys.UI.DomEvent.removeHandler(this._radioR,'mousedown',this._mouseDownDelegate);
        }
        if(this._radioG!=null) {
            Sys.UI.DomEvent.removeHandler(this._radioG,'click',this._radioClickedDelegate);
            Sys.UI.DomEvent.removeHandler(this._radioG,'mousedown',this._mouseDownDelegate);
        }
        if(this._radioB!=null) {
            Sys.UI.DomEvent.removeHandler(this._radioB,'click',this._radioClickedDelegate);
            Sys.UI.DomEvent.removeHandler(this._radioB,'mousedown',this._mouseDownDelegate);
        }
        if(this._inputHue!=null)
            Sys.UI.DomEvent.removeHandler(this._inputHue,'change',this._inputChangedDelegate);
        if(this._inputSaturation!=null)
            Sys.UI.DomEvent.removeHandler(this._inputSaturation,'change',this._inputChangedDelegate);
        if(this._inputLuminosity!=null)
            Sys.UI.DomEvent.removeHandler(this._inputLuminosity,'change',this._inputChangedDelegate);
        if(this._inputR!=null)
            Sys.UI.DomEvent.removeHandler(this._inputR,'change',this._inputChangedDelegate);
        if(this._inputG!=null)
            Sys.UI.DomEvent.removeHandler(this._inputG,'change',this._inputChangedDelegate);
        if(this._inputB!=null)
            Sys.UI.DomEvent.removeHandler(this._inputB,'change',this._inputChangedDelegate);
        if(this._inputHtmlColor!=null)
            Sys.UI.DomEvent.removeHandler(this._inputHtmlColor,'change',this._inputChangedDelegate);
        if(this._radioClickedDelegate!=null)
            delete this._radioClickedDelegate;
        if(this._mouseDownDelegate!=null)
            delete this._mouseDownDelegate;
        if(this._inputChangedDelegate!=null)
            delete this._inputChangedDelegate;
        if(this._okButtonDelegate) {
            this._colorPickerWindow.remove_okButton(this._okButtonDelegate);
            delete this._okButtonDelegate;
        }
        if(this._cancelButtonDelegate) {
            this._colorPickerWindow.remove_cancelButton(this._cancelButtonDelegate);
            delete this._cancelButtonDelegate;
        }
        if(this._colorPickerWindow) {
            this._colorPickerWindow.dispose();
            delete this._colorPickerWindow;
        }
        if(this._targetControlDelegate) {
            if(this._targetControlId!=null) {
                var targetControl=$get(this._targetControlId);
                if(targetControl!=null)
                    Sys.UI.DomEvent.removeHandler(targetControl,this._targetControlActivationOn,this._targetControlDelegate);
            }
        }
        delete this._targetControlDelegate;
        Typps.ColorPicker.callBaseMethod(this,'dispose');
    },
    initialize: function () {
        Typps.ColorPicker.callBaseMethod(this,'initialize');
        this._hue=new Array(0,30,60,90,120,150,180,210,240,270,300,330);
        this._saturation=new Array(0,10,15,25,30,45,55,65,75,80,90,100);
        this._lightness=new Array(0,10,20,30,40,50,55,60,70,80,90,100);
        this._defaultHtmlColor='#000000';
        this._selectionBorderColor='#ffffff';
        this._colorPickerWindow=null;
        this._updatePanelProgress=null;
        this._colorSwatch=null;
        this._previewBox=null;
        this._lastSelectedCell=null;
        this._inputHue=null;
        this._inputSaturation=null;
        this._inputLuminosity=null;
        this._radioR=null;
        this._inputR=null;
        this._radioG=null;
        this._inputG=null;
        this._radioB=null;
        this._inputB=null;
        this._inputHtmlColor=null;
        this._radioClickedDelegate=null;
        this._inputChangedDelegate=null;
        this._postbackElement=$get(this.get_id()+'_properties');
        this._colorPickerWindowId = this.get_id() + '_window';

        this._form = Typps.Utility.getForm(this._formElementId);

        if(this._targetControlId!=null) {
            var targetControl=$get(this._targetControlId);
            if(targetControl!=null) {
                if(this._targetControlDelegate===null)
                    this._targetControlDelegate=Function.createDelegate(this,this._targetControlHandler);
                Sys.UI.DomEvent.addHandler(targetControl,this._targetControlActivationOn,this._targetControlDelegate);
            }
        }
        if(this._mouseDownDelegate===null)
            this._mouseDownDelegate=Function.createDelegate(this,this._mouseDownHandler);
        if(this._updatePanelProgress===null)
            this._updatePanelProgress=$find(this._updatePanelProgressId);
        if(this._abortRequestHandlerDelegate===null)
            this._abortRequestHandlerDelegate=Function.createDelegate(this,this._abortRequestHandler);
        if(this._abortRequestHandlerDelegate===null&&this._updatePanelProgress!=null)
            this._updatePanelProgress.add_abortRequest(this._abortRequestHandlerDelegate);
    },
    _mouseDownHandler: function (args) {
        args.preventDefault();
    },
    _createColorPickerDesigner: function (markup) {
        var container=document.createElement('div');
        var colorPickerContent=Typps.Utility.getAdjacentHTML(markup,container).firstChild;
        this._colorPickerWindow=this._createModalPopup(colorPickerContent,this._colorPickerWindowId,false);
        if(this._okButtonDelegate===null)
            this._okButtonDelegate=Function.createDelegate(this,this._okButtonHandler);

        if(this._cancelButtonDelegate===null)
            this._cancelButtonDelegate=Function.createDelegate(this,this._cancelButtonHandler);

        if(this._radioClickedDelegate===null) {
            this._radioClickedDelegate=Function.createDelegate(this,this._radioClickedHandler);
        }
        if(this._inputChangedDelegate===null) {
            this._inputChangedDelegate=Function.createDelegate(this,this._inputChangedHandler);
        }
        if(this._colorSelectDelegate===null) {
            this._colorSelectDelegate=Function.createDelegate(this,this._colorSelectHandler);
        }
        if(this._colorMouseOverDelegate===null) {
            this._colorMouseOverDelegate=Function.createDelegate(this,this._colorMouseOverHandler);
        }
        if(this._colorMouseOutDelegate===null) {
            this._colorMouseOutDelegate=Function.createDelegate(this,this._colorMouseOutHandler);
        }
        this._colorPickerWindow.add_okButton(this._okButtonDelegate);
        this._colorPickerWindow.add_cancelButton(this._cancelButtonDelegate);
        this._colorSwatch=$get(this.get_id()+'_colorswatch');
        this._previewBox=$get(this.get_id()+'_previewbox');
        if(this._previewBox!=null)
            this._previewBox.innerHTML='&nbsp;';

        this._inputHue=$get(this.get_id()+'_inputhue');
        this._inputSaturation=$get(this.get_id()+'_inputsaturation');
        this._inputLuminosity=$get(this.get_id()+'_inputluminosity');
        this._radioR=$get(this.get_id()+'_radior');

        this._inputR=$get(this.get_id()+'_inputr');
        this._radioG=$get(this.get_id()+'_radiog');
        this._inputG=$get(this.get_id()+'_inputg');
        this._radioB=$get(this.get_id()+'_radiob');
        this._inputB=$get(this.get_id()+'_inputb');
        this._inputHtmlColor=$get(this.get_id()+'_htmlcolor');

        if(this._radioR!=null) {
            Sys.UI.DomEvent.addHandler(this._radioR,'click',this._radioClickedDelegate);
            Sys.UI.DomEvent.addHandler(this._radioR,'mousedown',this._mouseDownDelegate);
        }
        if(this._radioG!=null) {
            Sys.UI.DomEvent.addHandler(this._radioG,'click',this._radioClickedDelegate);
            Sys.UI.DomEvent.addHandler(this._radioG,'mousedown',this._mouseDownDelegate);
        }
        if(this._radioB!=null) {
            Sys.UI.DomEvent.addHandler(this._radioB,'click',this._radioClickedDelegate);
            Sys.UI.DomEvent.addHandler(this._radioB,'mousedown',this._mouseDownDelegate);
        }
        if(this._inputHue!=null) {
            Sys.UI.DomEvent.addHandler(this._inputHue,'change',this._inputChangedDelegate);
            this._inputHue.value=0;
        }
        if(this._inputSaturation!=null) {
            Sys.UI.DomEvent.addHandler(this._inputSaturation,'change',this._inputChangedDelegate);
            this._inputSaturation.value=100;
            this._inputSaturation.maxLength=3;
        }
        if(this._inputLuminosity!=null) {
            Sys.UI.DomEvent.addHandler(this._inputLuminosity,'change',this._inputChangedDelegate);
            this._inputLuminosity.value=50;
            this._inputLuminosity.maxLength=3;
        }
        if(this._inputR!=null) {
            Sys.UI.DomEvent.addHandler(this._inputR,'change',this._inputChangedDelegate);
            this._inputR.value=255;
            this._inputR.maxLength=3;
        }
        if(this._inputG!=null) {
            Sys.UI.DomEvent.addHandler(this._inputG,'change',this._inputChangedDelegate);
            this._inputG.value=255;
            this._inputG.maxLength=3;
        }
        if(this._inputB!=null) {
            Sys.UI.DomEvent.addHandler(this._inputB,'change',this._inputChangedDelegate);
            this._inputB.value=255;
            this._inputB.maxLength=3;
        }
        if(this._inputHtmlColor!=null) {
            Sys.UI.DomEvent.addHandler(this._inputHtmlColor,'change',this._inputChangedDelegate);
            this._inputHtmlColor.maxLength=6;
        }
        this._createColorPalette();
    },
    _radioClickedHandler: function (args) {
        var id=args.target.id.toLowerCase();
        id=id.substring(id.lastIndexOf('_'));
        var r=0;
        var g=0;
        var b=0;
        switch(id) {
            case '_radior':
                r=255;
                this._updateColorPalette(0,Typps.ColorPicker.Section.ColorMatrix);
                this._slideToHue(0);
                break;
            case '_radiog':
                g=255;
                this._updateColorPalette(120,Typps.ColorPicker.Section.ColorMatrix);
                this._slideToHue(120);
                break;
            case '_radiob':
                b=255;
                this._updateColorPalette(240,Typps.ColorPicker.Section.ColorMatrix);
                this._slideToHue(240);
                break;
        }
        var color=this._rgbToHtmlColorCode(r,g,b);
        this._updateNewColor(color,3);

        var eventArgs=new Typps.EventArgs();
        eventArgs.set_commandName(this._commandName);
        eventArgs.set_commandArgument(color);
        eventArgs.set__innerArgs(args);
        //a selection takes place anyway since the color has changed, so fire the event
        var hnd=this.get_events().getHandler('colorSelect');
        if(hnd) hnd(this,eventArgs);
    },
    _inputChangedHandler: function (args) {
        var id=args.target.id.toLowerCase();
        id=id.substring(id.lastIndexOf('_'));
        var h=parseInt(this._inputHue.value);
        var s=parseInt(this._inputSaturation.value);
        var l=parseInt(this._inputLuminosity.value);
        var r=parseInt(this._inputR.value);
        var g=parseInt(this._inputG.value);
        var b=parseInt(this._inputB.value);
        var color=this._inputHtmlColor.value;
        var updateColorPalette=true;
        var udpateMode=3;
        switch(id) {
            case '_inputhue':
            case '_inputsaturation':
            case '_inputluminosity':
                h=isNaN(h)?0:h;
                if(h>359||h<0) {
                    h=0;
                    this._inputHue.value=h;
                }
                s=isNaN(s)?100:s;
                l=isNaN(l)?100:l;
                if(s>100||s<0) {
                    s=100;
                    this._inputSaturation.value=s;
                }
                if(l>100||l<0) {
                    l=100;
                    this._inputLuminosity.value=l;
                }
                var p=this._hslToRgb(h/360,s/100,l/100);
                color=this._rgbToHtmlColorCode(Math.round(p.r*255),Math.round(p.g*255),Math.round(p.b*255)).substring(1);
                if(id!='_inputhue') {
                    updateColorPalette=false;
                    updateMode=1;
                }
                break;
            case '_inputr':
            case '_inputg':
            case '_inputb':
                r=isNaN(r)?255:r;
                g=isNaN(g)?255:g;
                b=isNaN(b)?255:b;
                if(r>255||r<0) {
                    r=255;
                    this._inputR.value=r;
                }
                if(g>255||g<0) {
                    g=255;
                    this._inputG.value=g;
                }
                if(b>255||b<0) {
                    b=255;
                    this._inputB.value=b;
                }
                h=this._rgbToHsl(r,g,b)[0]*360;
                color=this._rgbToHtmlColorCode(r,g,b).substring(1);
                updateMode=0;
                break;
            case '_htmlcolor':
                var regex=/^[0-9a-fA-F\s]+$/;
                if(!regex.test(color)) {
                    this._inputHtmlColor.value='';
                    return;
                }
                updateColorPalette=false;
                updateMode=3;
                break;
        }
        this._updateNewColor('#'+color,updateMode);
        if(updateColorPalette) {
            var hue=this._nearest(h,this._hue);
            this._updateColorPalette(h,Typps.ColorPicker.Section.ColorMatrix);
            this._slideToHue(hue);
        }
        var eventArgs=new Typps.EventArgs();
        eventArgs.set_commandName(this._commandName);
        eventArgs.set_commandArgument('#'+color);
        eventArgs.set_innerArgs(args);
        //a selection takes place anyway since the color has changed, so fire the event
        var hnd=this.get_events().getHandler('colorSelect');
        if(hnd) hnd(this,eventArgs);
    },

    _createModalPopup: function (content,id,makeFormChild) {
        var ok=this.get_id()+'_btnok';
        var cancel=this.get_id()+'_btncancel';
        var title=(this._title==''||this._title==null)?content.title:this._title;
        var popup=$create(Typps.ModalPopup,
            { id: id,display: true,content: content,title: title,isModal: true,className: this._className,shaderColor: this._shaderColor,shaderOpacity: this._shaderOpacity,okButtonId: ok,cancelButtonId: cancel,makeFormChild: makeFormChild,formElementId: this._formElementId },
            null,null,null);

        content.removeAttribute('title');
        return popup;
    },
    _targetControlHandler: function (args) {
        if(this._updatePanelProgress===null)
            this._updatePanelProgress=$find(this._updatePanelProgressId);

        if(this._abortRequestHandlerDelegate===null&&this._updatePanelProgress!=null)
            this._updatePanelProgress.add_abortRequest(this._abortRequestHandlerDelegate);
        this._colorPickerDesignerInitCallback();
        var h=this.get_events().getHandler('target');
        if(h) h(this,args);
        return false;
    },
    _okButtonHandler: function (args) {
        var color=this._inputHtmlColor.value;
        color=(color.length>0)?'#'+color:'';
        var eventArgs=new Typps.EventArgs();
        eventArgs.set_commandName(this._commandName);
        eventArgs.set_commandArgument(color);
        eventArgs.set_innerArgs(args);

        var h=this.get_events().getHandler('ok');
        if(h) h(this,eventArgs);
        this._postbackElement.value=color;
    },
    _cancelButtonHandler: function (args) {
        var h=this.get_events().getHandler('cancel');
        if(h) h(this,args);
        this._postbackElement.value='';
    },
    _abortRequestHandler: function (args) { },
    initializeRequest: function () {
        this._colorPickerDesignerInitCallback();
    },
    _colorPickerDesignerInitCallback: function () {
        var argument=Typps.Utility.getCommandArgument('colorpicker',this.get_callbacks());
        var formKeyValuePair={ formdata: argument.commandArgument };
        if(this._colorPickerWindow==null)
            this._fireUpdatePanelTrigger(formKeyValuePair,argument.commandArgument,argument.message);
        else
            this.show(true);
    },
    show: function (val) {
        if(this._colorPickerWindow!==null)
            this._colorPickerWindow.show(val);
    },
    resetTitle: function (val) {
        if(this._colorPickerWindow==null)
            this.set_title(val);
        else
            this._colorPickerWindow.resetCaption(val);
    },
    reset: function () {
        this._inputHue.value=0;
        this._inputSaturation.value=100;
        this._inputLuminosity.value=50;
        this._inputR.value=255;
        this._inputG.value=255;
        this._inputB.value=255;

        var hue=this._nearest(0,this._hue);
        this._updateNewColor('#000000',3);
        this._updateColorPalette(h,Typps.ColorPicker.Section.ColorMatrix);
        this._slideToHue(hue);
    },
    _hslToRgb: function (h,s,l) {
        var p={ r: 0,g: 0,b: 0 };
        var r,g,b,m1,m2;
        if(l<=0.5)
            m2=l*(s+1);
        else
            m2=(l+s)-(l*s);
        m1=(l*2)-m2;
        p.r=this._hueToRgb(m1,m2,h+1/3);
        p.g=this._hueToRgb(m1,m2,h);
        p.b=this._hueToRgb(m1,m2,h-1/3);
        return p;
    },
    _hueToRgb: function (m1,m2,h) {
        if(h<0) h=h+1;
        if(h>1) h=h-1;
        if(h*6<1) return m1+(m2-m1)*h*6;
        if(h*2<1) return m2;
        if(h*3<2) return m1+(m2-m1)*(2/3-h)*6;
        return m1;
    },
    _rgbToHsl: function (r,g,b) {
        r/=255,g/=255,b/=255;
        var max=Math.max(r,g,b),min=Math.min(r,g,b);
        var h,s,l=(max+min)/2;

        if(max==min) {
            h=s=0;
        } else {
            var d=max-min;
            s=l>0.5?d/(2-max-min):d/(max+min);
            switch(max) {
                case r: h=(g-b)/d+(g<b?6:0);break;
                case g: h=(b-r)/d+2;break;
                case b: h=(r-g)/d+4;break;
            }
            h/=6;
        }
        return [h,s,l];
    },
    _parseRgb: function (n) {
        var p={ r: 0,g: 0,b: 0 };
        var start=n.indexOf('rgb(');
        if(start!= -1) {
            start=4;
            var color=n.substr(start,((n.length-1)-start));
            var split=color.split(',');
            p.r=parseInt(split[0]);
            p.g=parseInt(split[1]);
            p.b=parseInt(split[2]);
            return p;
        }
        return n;
    },
    _hexToRgb: function (hex) {
        var p={ r: 0,g: 0,b: 0 };
        p.r=parseInt((this._cutHex(hex)).substring(0,2),16);
        p.g=parseInt((this._cutHex(hex)).substring(2,4),16);
        p.b=parseInt((this._cutHex(hex)).substring(4,6),16);
        return p;
    },
    _cutHex: function (hex) {
        return (hex.charAt(0)=="#")?hex.substring(1,7):hex;
    },
    _toHex: function (n) {
        if(n==null) return '00';
        n=parseInt(n);
        if(isNaN(n)||n==0) return '00';
        n=Math.max(0,n);
        n=Math.min(n,255);
        n=Math.round(n);
        return '0123456789ABCDEF'.charAt((n-n%16)/16)
              +'0123456789ABCDEF'.charAt(n%16);
    },
    _rgbToHtmlColorCode: function (r,g,b) {
        return String.format('#{0}{1}{2}',
        this._toHex(r),
        this._toHex(g),
        this._toHex(b));
    },
    _updateNewColor: function (color,updateMode) {
        this._resetOpacity(this._lastSelectedCell);
        this._lastSelectedCell=null;
        var c=this._getHtmlColorAndRgb(color);
        var p=c.primary;
        var hsl=this._rgbToHsl(p.r,p.g,p.b);
        p=this._hslToRgb(hsl[0],hsl[1],hsl[2]);
        var r=Math.round(p.r*255);
        var g=Math.round(p.g*255);
        var b=Math.round(p.b*255);
        this._previewBox.style.backgroundColor=color;
        this._inputHtmlColor.value=color.substring(1);
        if(updateMode==1||updateMode==3) {
            this._inputR.value=r;
            this._inputG.value=g;
            this._inputB.value=b;
        }
        if(updateMode==0||updateMode==3) {
            this._inputHue.value=Math.round(hsl[0]*360);
            this._inputSaturation.value=Math.round(hsl[1]*100);
            this._inputLuminosity.value=Math.round(hsl[2]*100);
        }
    },
    _updateColorPalette: function (h,section) {
        var table=$get(this.get_id()+'_colorPicker');
        var tBody=table.getElementsByTagName('tbody')[0];
        this._resetOpacity(this._lastSelectedCell);
        this._lastSelectedCell=null;
        var flag1=(section==2||section==3)?true:false;
        for(var num1=0;num1<this._saturation.length;num1++) {
            var tr=tBody.childNodes[num1];
            var s=this._saturation[num1];
            for(var num2=0;num2<this._lightness.length;num2++) {
                var td=tr.childNodes[num2];
                var l=this._lightness[num2];
                var flag2=false;
                if(section==Typps.ColorPicker.Section.ColorMatrix||
                    section==Typps.ColorPicker.Section.ColorMatrixWithSelection) {
                    if(num2<(tr.childNodes.length-2))
                        flag2=true;
                }
                else if(section==Typps.ColorPicker.Section.HuePalette) {
                    if(num2==(tr.childNodes.length-2))
                        flag2=true;
                }
                else {
                    if(num2!=(tr.childNodes.length-1))
                        flag2=true;
                }
                if(flag2) {
                    var p=this._hslToRgb(h/360,s/100,l/100);
                    var htmlColor=this._rgbToHtmlColorCode(p.r*255,p.g*255,p.b*255);
                    var a=td.getElementsByTagName('a')[0];
                    a.style.backgroundColor=htmlColor;
                    a.style.borderColor=htmlColor;
                    td.style.backgroundColor=htmlColor;
                    if(flag1) {
                        var p2=this._hslToRgb(h/360,100/100,50/100);
                        if(p.r==p2.r&&p.g==p2.g&&p.b==p2.b) {
                            this._selectElement(td);
                            this._lastSelectedCell=td;
                            flag1=false;
                        }
                    }
                }
            }
        }
    },
    _slideToHue: function (h) {
        var table=$get(this.get_id()+'_colorPicker');
        var tBody=table.getElementsByTagName('tbody')[0];
        var flag1=false;
        for(num1=0;num1<tBody.childNodes.length;num1++) {
            var tr=tBody.childNodes[num1];
            for(num2=0;num2<tr.childNodes.length;num2++) {
                var td=tr.childNodes[num2];
                if(num2==(tr.childNodes.length-2)) {
                    var color=td.style.backgroundColor;
                    var td2=tr.childNodes[num2+1];
                    var b=td2.getElementsByTagName('b')[0];
                    var p=this._getHtmlColorAndRgb(color).primary;
                    var hsl=this._rgbToHsl(p.r,p.g,p.b);
                    b.style.visibility='hidden';
                    if(h==Math.round(hsl[0]*360)&&!flag1) {
                        b.style.visibility='visible';
                        flag1=true;
                    }
                }
            }
        }
    },
    _createTable: function (spacing,padding) {
        var table=document.createElement('table');
        table.id=this.get_id()+'_colorPicker';
        table.border=0;
        table.cellSpacing=spacing;
        table.cellPadding=padding;
        table.style.width='100%';
        table.style.backgroundColor='#000';
        var oTBody=document.createElement('tbody');
        table.appendChild(oTBody);
        Typps.Utility.setFloat(table,'left');
        return table;
    },
    _createHuePalette: function (tbody) {
        for(var num1=0;num1<this._hue.length;num1++) {
            var tr=tbody.childNodes[num1];
            var td=document.createElement('td');
            var a=document.createElement('a');
            var indicator=document.createElement('td');
            var b=document.createElement('b');

            var h,s,l;
            h=this._hue[num1];
            s=100/100;
            l=50/100;
            var p=this._hslToRgb(h/360,s,l);
            var htmlColor=this._rgbToHtmlColorCode(p.r*255,p.g*255,p.b*255);
            td.style.backgroundColor=htmlColor;
            td.style.cursor='pointer';
            a.href='javascript:void(0);';
            a.style.textDecoration='none';
            a.style.display='block';
            a.style.border='2px solid '+htmlColor;
            a.style.backgroundColor=htmlColor;
            a.innerHTML='&nbsp;';
            b.innerHTML='&#171;';
            indicator.style.width='10px';
            indicator.style.color=htmlColor;
            if(num1!=0)
                b.style.visibility='hidden';
            tr.appendChild(td);
            td.appendChild(a);
            tr.appendChild(indicator);
            indicator.appendChild(b);
            this._attachColorSwatchEvents(a);
        }
    },
    _createColorPalette: function () {
        var h=359;//default red
        var flag1=false;
        var table=this._createTable(1,0);
        var tbody=table.getElementsByTagName("tbody")[0];
        for(var num2=0;num2<this._saturation.length;num2++) {
            var s=this._saturation[num2]/100;
            var tr=document.createElement('tr');
            tbody.appendChild(tr);
            for(var num3=0;num3<this._lightness.length;num3++) {
                var l=this._lightness[num3]/100;
                var td=document.createElement('td');
                var a=document.createElement('a');
                td.style.cursor='pointer';
                var p=this._hslToRgb(h/360,s,l);
                var htmlColor=this._rgbToHtmlColorCode(p.r*255,p.g*255,p.b*255);
                td.style.backgroundColor=htmlColor;
                a.style.border='2px solid '+htmlColor;
                a.style.backgroundColor=htmlColor;
                a.href='javascript:void(0);';
                a.style.display='block';
                a.style.textDecoration='none';
                a.innerHTML='&nbsp;';
                tr.appendChild(td);
                td.appendChild(a);
                if(this._defaultHtmlColor==htmlColor.toLowerCase()&&!flag1) {
                    this._lastSelectedCell=td;
                    this._selectElement(td);
                    flag1=true;
                }
                this._attachColorSwatchEvents(a);
            }
        }
        if(this._colorSwatch!=null)
            this._colorSwatch.appendChild(table);

        this._createHuePalette(tbody);
    },
    _attachColorSwatchEvents: function (el) {
        Sys.UI.DomEvent.addHandler(el,'click',this._colorSelectDelegate);
        Sys.UI.DomEvent.addHandler(el,'mousedown',this._mouseDownDelegate);
        Sys.UI.DomEvent.addHandler(el,'mouseover',this._colorMouseOverDelegate);
        Sys.UI.DomEvent.addHandler(el,'mouseout',this._colorMouseOutDelegate);
    },
    _nearest: function (n,list) {
        var nearest=0;
        for(num1=0;num1<list.length;num1++) {
            var hue=list[num1];
            if(n>hue&&num1!=(list.length-1)) {
                nearest=hue;
            }
            else if(n==hue) {
                return hue;
            }
            else {
                var prev=list[num1-1];
                var distance1=Math.abs(n-hue);
                var distance2=Math.abs(n-prev);
                nearest=(distance1<=distance2)?hue:prev;
                break;
            }
        }
        return nearest;
    },
    _resetOpacity: function (td) {
        if(td==null) return;
        var a=td.getElementsByTagName('a')[0];
        Typps.Utility.setTransparency(td,100);
        a.style.borderColor=td.style.backgroundColor;
    },
    _selectElement: function (td) {
        if(td==null) return;
        var c=this._getHtmlColorAndRgb(td.style.backgroundColor);
        var a=td.getElementsByTagName('a')[0];
        a.style.borderColor=this._selectionBorderColor;
        this._previewBox.style.backgroundColor=c.toHtmlColor;
        this._inputHtmlColor.value=c.toHtmlColor.substring(1);
        Typps.Utility.setTransparency(td,30);
    },
    _colorMouseOutHandler: function (args) {
        var td=args.target.parentNode;
        var color=td.style.backgroundColor;
        var eventArgs=new Typps.EventArgs();
        eventArgs.set_commandName(this._commandName);
        eventArgs.set_commandArgument(color);
        eventArgs.set_innerArgs(args);
        var h=this.get_events().getHandler('colorMouseOut');
        if(h) h(this,eventArgs);
        if(this._lastSelectedCell==null||td!=this._lastSelectedCell)
            this._resetOpacity(td);
    },
    _colorMouseOverHandler: function (args) {
        var td=args.target.parentNode;
        var color=td.style.backgroundColor;
        var eventArgs=new Typps.EventArgs();
        eventArgs.set_commandName(this._commandName);
        eventArgs.set_commandArgument(color);
        eventArgs.set_innerArgs(args);
        var h=this.get_events().getHandler('colorMouseOver');
        if(h) h(this,eventArgs);
        var a=td.getElementsByTagName('a')[0];
        a.style.borderColor=this._selectionBorderColor;
        Typps.Utility.setTransparency(td,30);
    },
    _colorSelectHandler: function (args) {
        var td=args.target.parentNode;
        var tr=args.target.parentNode.parentNode;
        var color=td.style.backgroundColor;

        var cellIndex=td.cellIndex;
        var section= -1;
        var len=tr.childNodes.length;
        if(cellIndex==len-2)
            section=1;//huepalette
        else if(cellIndex<len-2)
            section=0;//colormatrix

        var c=this._getHtmlColorAndRgb(color);
        var p=c.primary;

        var eventArgs=new Typps.EventArgs();
        eventArgs.set_commandName(this._commandName);
        eventArgs.set_commandArgument(c.toHtmlColor);
        eventArgs.set_innerArgs(args);



        var hsl=this._rgbToHsl(p.r,p.g,p.b);
        this._inputR.value=p.r;
        this._inputG.value=p.g;
        this._inputB.value=p.b;
        this._inputHue.value=Math.round(hsl[0]*360);
        this._inputSaturation.value=Math.round(hsl[1]*100);
        this._inputLuminosity.value=Math.round(hsl[2]*100);
        if(section==0) {
            this._resetOpacity(this._lastSelectedCell);
            this._selectElement(td);
            this._lastSelectedCell=td;
        }
        if(section==1) {
            var h=Math.round(hsl[0]*360);
            this._updateColorPalette(h,Typps.ColorPicker.Section.ColorMatrixWithSelection);
            this._slideToHue(h);
        }

        var hnd=this.get_events().getHandler('colorSelect');
        if(hnd) hnd(this,eventArgs);
    },
    _getHtmlColorAndRgb: function (color) {
        var c={ primary: { r: 0,g: 0,b: 0 },toHtmlColor: '' };
        if(color.indexOf('#')== -1) {
            c.primary=this._parseRgb(color);
            c.toHtmlColor=this._rgbToHtmlColorCode(c.primary.r,c.primary.g,c.primary.b);
        }
        else {
            c.primary=this._hexToRgb(color);
            c.toHtmlColor=color;
        }
        return c;
    },
    _beginRequestHandler: function (sender,args) {
        var h=this.get_events().getHandler('beginWebRequest');
        if(h) h(this,args);
    },
    _endRequestHandler: function (sender,args) {
        var h;
        if(!sender.get_responseAvailable()) {
            h=this.get_events().getHandler('endWebRequest');
            if(h) h(this,args);
            return;
        }
        var eventArgs=new Typps.EventArgs();
        var parts=sender.get_responseData().split(String.format('$callbackdata${0}$sep$',this.get_id()));
        var key=parts[0];
        var value=parts[1];
        eventArgs.set_commandName(key);
        eventArgs.set_commandArgument(value);
        eventArgs.set_innerArgs(args);
        h=this.get_events().getHandler('endWebRequest');
        if(h) h(this,eventArgs);

        switch(key) {
            case 'ColorPickerDesignerRequest':
                this._createColorPickerDesigner(value);
                h=this.get_events().getHandler('colorPickerInitialize');
                if(h) h(this,args);
                break;
        }
    },
    _makeWebRequest: function (eventArgs,formKeyValuePair) {
        var pageManager=Sys.WebForms.PageRequestManager.getInstance();
        var formBody=Typps.Utility.getFormKeyValuePair(this._uniqueId,formKeyValuePair,this._form,this._postbackAllFormData);
        var request=new Sys.Net.WebRequest();
        request.set_url(this._form.action);
        request.get_headers()['X-MicrosoftAjax']='Delta=true';
        request.get_headers()['Cache-Control']='no-cache';
        request.set_timeout(pageManager._asyncPostBackTimeout);
        request.set_body(formBody);
        if(this._updatePanelProgress===null)
            this._updatePanelProgress=$find(this._updatePanelProgressId);
        if(this._updatePanelProgress===null) return;

        this._updatePanelProgress.set_loadingMessage(eventArgs.get_commandArgument());
        if(this._beginRequestHandlerDelegate==null) {
            this._beginRequestHandlerDelegate=Function.createDelegate(this,this._beginRequestHandler);
            this._updatePanelProgress.add_beginRequest(this._beginRequestHandlerDelegate);
        }
        if(this._endRequestHandlerDelegate==null) {
            this._endRequestHandlerDelegate=Function.createDelegate(this,this._endRequestHandler);
            this._updatePanelProgress.add_endRequest(this._endRequestHandlerDelegate);
        }
        this._updatePanelProgress._makeWebRequest(request);
    },
    _fireUpdatePanelTrigger: function (formKeyValuePair,commandName,message) {
        var eventArgs=new Typps.EventArgs();
        eventArgs.set_commandName(commandName);
        eventArgs.set_commandArgument(message);
        this._makeWebRequest(eventArgs,formKeyValuePair);
    },
    _addCssClass: function (elem,className) {
        Typps.Utility.addRemoveClassName(elem,className,Typps.Perform.Add);
    },
    _removeCssClass: function (elem,className) {
        Typps.Utility.addRemoveClassName(elem,className,Typps.Perform.Remove);
    }
}
Typps.ColorPicker.registerClass('Typps.ColorPicker',Sys.UI.Control);
Typps.ColorPicker.Section=function () { };
Typps.ColorPicker.Section.prototype=
{
    ColorMatrix: 0,
    HuePalette: 1,
    Both: 2,
    ColorMatrixWithSelection: 3
}
Typps.ColorPicker.Section.registerEnum('Typps.ColorPicker.Section');
Typps.ColorPicker.Update=function () { };
Typps.ColorPicker.Update.prototype=
{
    Hsl: 0,
    Rgb: 1,
    Palette: 2,
    All: 3
}
Typps.ColorPicker.Update.registerEnum('Typps.ColorPicker.Update');
// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager 
// that this is the end of the script.
if(typeof (Sys)!=='undefined') Sys.Application.notifyScriptLoaded();